package com.example.a02back.service.impl;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.lang.UUID;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.example.a02back.common.RedisKey;
import com.example.a02back.entity.User;
import com.example.a02back.mapper.UserMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.spec.AlgorithmParameterSpec;
import java.util.Date;

/**
 * @ClassName AuthServicelmpl
 * @Description
 * @Author SimpChaos
 * @Date 2022/7/7 16:03
 * @Version 1.0
 **/
@Slf4j
@Service
public class AuthServicelmpl {

    @Value("${weixin.appid}")
    private String appid;

    @Value("${weixin.secret}")
    private String secret;

    @Resource
    StringRedisTemplate stringRedisTemplate;

    @Resource
    private UserMapper usermapper;


    /**
     * @Description: 访问微信服务器获得res
     * @Author: SimpChaos
     * @Date: 2022/7/7 9:01
     * @Param: String code
     * @Return: String s
     */
    public String getSession(String code) {

        String url = "https://api.weixin.qq.com/sns/jscode2session?appid={0}&secret={1}&js_code={2}&grant_type=authorization_code";
        String replaceUrl = url.replace("{0}", appid).replace("{1}", secret).replace("{2}", code);
        String res = HttpUtil.get(replaceUrl);
        System.out.print(res);
        String s = UUID.randomUUID().toString();
        stringRedisTemplate.opsForValue().set(RedisKey.WX_SESSION_ID + s, res);
        return s;
    }


    public JSONObject wxDecrypt(String sessionId, String encryptedData, String vi) throws Exception{

        String json =  stringRedisTemplate.opsForValue().get(RedisKey.WX_SESSION_ID + sessionId);
        System.out.print(json);
        log.info("之前存储在redis中的信息："+json);
        //之前存储在redis中的信息：{"session_key":"G59Evf\/Em54X6WsFsrpA1g==","openid":"o2ttv5L2yufc4-VoSPhTyUnToY60"}
        JSONObject jsonObject = JSON.parseObject(json);
        return jsonObject;
    }

    public String getOpenid(JSONObject jsonObject) throws Exception{
        //之前存储在redis中的信息：{"session_key":"G59Evf\/Em54X6WsFsrpA1g==","openid":"o2ttv5L2yufc4-VoSPhTyUnToY60"}
        log.info("跑到这里了");
        return (String) jsonObject.get("openid");
    }

    public String getUserInfo(String sessionId, String encryptedData, String vi,JSONObject jsonObject) throws Exception {
        String sessionKey = (String) jsonObject.get("session_key");
        System.out.print(2);
        byte[] encData = cn.hutool.core.codec.Base64.decode(encryptedData);
        byte[] iv = cn.hutool.core.codec.Base64.decode(vi);
        byte[] key = Base64.decode(sessionKey);
        AlgorithmParameterSpec ivSpec = new IvParameterSpec(iv);
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
        cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
        return new String(cipher.doFinal(encData), "UTF-8");
    }


    public String getToken(String openid) {
        Date start = new Date();
        long currentTime = System.currentTimeMillis() + 1000*1800;//半小时有效时间
        Date end = new Date(currentTime);
        System.out.print(end);
        String token = "";

        token = JWT.create().withClaim("openid", openid).withIssuedAt(start).withExpiresAt(end)
                .sign(Algorithm.HMAC256(openid));//创造
        return token;

    }


    public  String getUidFromToken(String token){
        String openid = JWT.decode(token).getClaim("openid").asString();

        LambdaQueryWrapper<User> wrapper1 = new LambdaQueryWrapper<>();
        wrapper1.select(User::getUid).eq(User::getOid,openid);
        User user1 = usermapper.selectOne(wrapper1);
        return user1.getUid();
    }

}
